package cn.fzkj.helper;

import cn.fzkj.model.UploadResult;
import cn.fzkj.utils.ImageUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageReader;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.function.Supplier;

/**
 * @author mr
 * @description
 * @since 2024/4/30
 */
public interface FileHelper {

    MediaType IMAGE_TYPE = MediaType.valueOf("image/*");

    default String normalizeDirectory(@NonNull String dir) {
        Assert.hasText(dir, "directory must not be blank");
        return StringUtils.appendIfMissing(dir, File.separator);
    }

    default boolean isImageType(@NonNull MultipartFile file) {
        String mediaType = file.getContentType();
        return mediaType != null && IMAGE_TYPE.includes(MediaType.valueOf(mediaType));
    }

    /**
     * Update Metadata for image object.
     *
     * @param uploadResult updated result must not be null
     * @param file multipart file must not be null
     * @param thumbnailSupplier thumbnail supplier
     */
    default void handleImageMetadata(@NonNull MultipartFile file,
                                     @NonNull UploadResult uploadResult,
                                     @Nullable Supplier<String> thumbnailSupplier) {
        if (isImageType(file)) {
            // Handle image
            try (InputStream is = file.getInputStream()) {
                String extension = uploadResult.getSuffix();
                if (ImageUtils.EXTENSION_ICO.equals(extension)) {
                    BufferedImage icoImage =
                            ImageUtils.getImageFromFile(is, extension);
                    uploadResult.setWidth(icoImage.getWidth());
                    uploadResult.setHeight(icoImage.getHeight());
                } else {
                    ImageReader image =
                            ImageUtils.getImageReaderFromFile(is, extension);
                    uploadResult.setWidth(image.getWidth(0));
                    uploadResult.setHeight(image.getHeight(0));
                }

                if (thumbnailSupplier != null) {
                    uploadResult.setThumbPath(thumbnailSupplier.get());
                }
            } catch (IOException | OutOfMemoryError e) {
                // ignore IOException and OOM
                LoggerFactory.getLogger(getClass()).warn("Failed to fetch image meta data", e);
            }
        }
        if (StringUtils.isBlank(uploadResult.getThumbPath())) {
            uploadResult.setThumbPath(uploadResult.getFilePath());
        }
    }

    @NonNull
    UploadResult upload(@NonNull MultipartFile file);

    void delete(@NonNull String key);
}
